from flask import Blueprint, request
from flask_jwt_extended import jwt_required, get_jwt_identity
from app import db
from app.models import User, ExamRecord, Certificate
from app.utils.response import success_response, error_response, paginated_response
from app.utils.decorators import admin_required
from app.models.operation_log import OperationLog
from loguru import logger

users_bp = Blueprint('users', __name__)

@users_bp.route('/profile', methods=['GET'])
@jwt_required()
def get_profile():
    """获取用户个人资料"""
    try:
        current_user_id = get_jwt_identity()
        user = User.query.get(current_user_id)
        
        if not user:
            return error_response('用户不存在', 404)
        
        return success_response(user.to_dict())
        
    except Exception as e:
        logger.error(f"获取用户资料失败: {e}")
        return error_response('获取用户资料失败', 500)

@users_bp.route('/profile', methods=['PUT'])
@jwt_required()
def update_profile():
    """更新用户个人资料"""
    try:
        current_user_id = get_jwt_identity()
        user = User.query.get(current_user_id)
        
        if not user:
            return error_response('用户不存在', 404)
        
        data = request.get_json()
        nickname = data.get('nickname')
        avatar_url = data.get('avatar_url')
        
        if nickname is not None:
            user.nickname = nickname
        if avatar_url is not None:
            user.avatar_url = avatar_url
        
        db.session.commit()
        
        return success_response(user.to_dict(), '资料更新成功')
        
    except Exception as e:
        logger.error(f"更新用户资料失败: {e}")
        return error_response('更新用户资料失败', 500)

@users_bp.route('/stats', methods=['GET'])
@jwt_required()
def get_user_stats():
    """获取用户统计数据"""
    try:
        current_user_id = get_jwt_identity()
        
        # 统计考试记录
        exam_records = ExamRecord.query.filter_by(user_id=current_user_id).all()
        total_exams = len(exam_records)
        passed_exams = len([r for r in exam_records if r.is_passed])
        total_score = sum(r.score for r in exam_records)
        avg_score = total_score / total_exams if total_exams > 0 else 0
        
        # 统计证书
        certificates = Certificate.query.filter_by(user_id=current_user_id, is_valid=True).all()
        certificate_count = len(certificates)
        
        # 获取排名
        from app.models import Leaderboard
        leaderboard_record = Leaderboard.query.filter_by(
            user_id=current_user_id,
            period_type='all_time'
        ).first()
        
        rank = leaderboard_record.rank_position if leaderboard_record else 0
        
        stats = {
            'total_exams': total_exams,
            'passed_exams': passed_exams,
            'pass_rate': (passed_exams / total_exams * 100) if total_exams > 0 else 0,
            'total_score': total_score,
            'avg_score': round(avg_score, 2),
            'certificate_count': certificate_count,
            'rank': rank
        }
        
        return success_response(stats)
        
    except Exception as e:
        logger.error(f"获取用户统计失败: {e}")
        return error_response('获取用户统计失败', 500)

# 管理员接口
@users_bp.route('/admin/', methods=['GET'])
@admin_required
def admin_get_users():
    """管理员获取用户列表"""
    try:
        page = request.args.get('page', 1, type=int)
        per_page = min(request.args.get('per_page', 10, type=int), 100)
        search = request.args.get('search', '')
        
        query = User.query
        
        if search:
            query = query.filter(
                db.or_(
                    User.nickname.contains(search),
                    User.openid.contains(search)
                )
            )
        
        pagination = query.order_by(User.created_at.desc()).paginate(
            page=page,
            per_page=per_page,
            error_out=False
        )
        
        users = []
        for user in pagination.items:
            user_dict = user.to_dict()
            
            # 添加统计数据
            exam_records = ExamRecord.query.filter_by(user_id=user.id).all()
            certificates = Certificate.query.filter_by(user_id=user.id, is_valid=True).all()
            
            user_dict['stats'] = {
                'exam_count': len(exam_records),
                'certificate_count': len(certificates),
                'last_login': user.last_login_at.isoformat() if user.last_login_at else None
            }
            
            users.append(user_dict)
        
        return paginated_response(
            users,
            page,
            per_page,
            pagination.total
        )
        
    except Exception as e:
        logger.error(f"管理员获取用户列表失败: {e}")
        return error_response('获取用户列表失败', 500)

@users_bp.route('/admin/<int:user_id>', methods=['GET'])
@admin_required
def admin_get_user_detail(user_id):
    """管理员获取用户详情"""
    try:
        user = User.query.get(user_id)
        if not user:
            return error_response('用户不存在', 404)
        
        user_dict = user.to_dict()
        
        # 获取考试记录
        exam_records = ExamRecord.query.filter_by(user_id=user_id).order_by(ExamRecord.created_at.desc()).limit(10).all()
        user_dict['exam_records'] = [record.to_dict() for record in exam_records]
        
        # 获取证书
        certificates = Certificate.query.filter_by(user_id=user_id, is_valid=True).order_by(Certificate.created_at.desc()).all()
        user_dict['certificates'] = [cert.to_dict() for cert in certificates]
        
        # 获取统计数据
        total_exams = len(exam_records)
        passed_exams = len([r for r in exam_records if r.is_passed])
        total_score = sum(r.score for r in exam_records)
        
        user_dict['stats'] = {
            'total_exams': total_exams,
            'passed_exams': passed_exams,
            'pass_rate': (passed_exams / total_exams * 100) if total_exams > 0 else 0,
            'total_score': total_score,
            'avg_score': total_score / total_exams if total_exams > 0 else 0,
            'certificate_count': len(certificates)
        }
        
        return success_response(user_dict)
        
    except Exception as e:
        logger.error(f"获取用户详情失败: {e}")
        return error_response('获取用户详情失败', 500)

@users_bp.route('/admin/<int:user_id>', methods=['PUT'])
@admin_required
def admin_update_user(user_id):
    """管理员更新用户信息"""
    try:
        user = User.query.get(user_id)
        if not user:
            return error_response('用户不存在', 404)
        
        data = request.get_json()
        nickname = data.get('nickname')
        avatar_url = data.get('avatar_url')
        is_active = data.get('is_active')
        
        if nickname is not None:
            user.nickname = nickname
        if avatar_url is not None:
            user.avatar_url = avatar_url
        if is_active is not None:
            user.is_active = is_active
        
        db.session.commit()
        
        # 记录操作日志
        current_admin_id = int(get_jwt_identity().split('_')[1])
        OperationLog.log_operation(
            action='update_user',
            description=f'更新用户信息: {user.nickname}',
            admin_id=current_admin_id,
            resource_type='user',
            resource_id=user.id
        )
        
        return success_response(user.to_dict(), '用户信息更新成功')
        
    except Exception as e:
        logger.error(f"更新用户信息失败: {e}")
        return error_response('更新用户信息失败', 500)

@users_bp.route('/admin/<int:user_id>', methods=['DELETE'])
@admin_required
def admin_delete_user(user_id):
    """管理员删除用户"""
    try:
        user = User.query.get(user_id)
        if not user:
            return error_response('用户不存在', 404)
        
        nickname = user.nickname
        
        # 删除相关数据
        ExamRecord.query.filter_by(user_id=user_id).delete()
        Certificate.query.filter_by(user_id=user_id).delete()
        
        # 删除用户
        db.session.delete(user)
        db.session.commit()
        
        # 记录操作日志
        current_admin_id = int(get_jwt_identity().split('_')[1])
        OperationLog.log_operation(
            action='delete_user',
            description=f'删除用户: {nickname}',
            admin_id=current_admin_id,
            resource_type='user',
            resource_id=user_id
        )
        
        return success_response(None, '用户删除成功')
        
    except Exception as e:
        logger.error(f"删除用户失败: {e}")
        return error_response('删除用户失败', 500)

@users_bp.route('/admin/stats', methods=['GET'])
@admin_required
def admin_get_user_stats():
    """管理员获取用户统计信息"""
    try:
        # 总用户数
        total_users = User.query.count()
        
        # 活跃用户数（最近7天有登录）
        from datetime import datetime, timedelta
        seven_days_ago = datetime.utcnow() - timedelta(days=7)
        active_users = User.query.filter(User.last_login_at >= seven_days_ago).count()
        
        # 今日新增用户
        today = datetime.utcnow().date()
        today_users = User.query.filter(
            db.func.date(User.created_at) == today
        ).count()
        
        # 用户增长趋势（最近30天）
        thirty_days_ago = datetime.utcnow() - timedelta(days=30)
        growth_data = []
        
        for i in range(30):
            date = thirty_days_ago + timedelta(days=i)
            count = User.query.filter(
                db.func.date(User.created_at) == date.date()
            ).count()
            growth_data.append({
                'date': date.strftime('%Y-%m-%d'),
                'count': count
            })
        
        stats = {
            'total_users': total_users,
            'active_users': active_users,
            'today_users': today_users,
            'active_rate': (active_users / total_users * 100) if total_users > 0 else 0,
            'growth_data': growth_data
        }
        
        return success_response(stats)
        
    except Exception as e:
        logger.error(f"获取用户统计失败: {e}")
        return error_response('获取用户统计失败', 500) 